;Assembles best with NASM or FASM

org 0x7c00	; (comment out this line for yasm compatibility)
;bits 16
use16
;Uncomment below lines for CD booting
;db 88h
;db 0
;dw 07C0h
;db 0
;db 0

;FAT12 USB HDD header

jmp short start
  nop
  db 'MSDOS5.0'
  db 0x00
  db 0x02                        ; bytes per sector
  db 0x40
  db 0x02                          ; sectors per cluster
  db 0x00
  db 0x02                         ; reserved sector count
  db 0x00
  db 0x02                          ; number of FATs
  db 0x00
  db 0x00                      ; root directory entries
  db 0xf8
  db 0xef                    ; sector count
  db 0x00
  db 0x3f                       ; media byte
  db 0x00
  db 0xff                          ; sectors per fat
  db 0x00
  db 0x00                         ; sectors per track
  db 0x00
  db 0x00                          ; number of heads
  db 0x00
  db 0xe0
  db 0xbf
  db 0x3b                          ; hidden sector count
  db 0x00
  db 0x80
  db 0x00
  db 0x29                          ; number of sectors huge
  db 0xb0                          ; drive number
  db 0xe6                          ; reserved
  db 0x5f                        ; signature
  db 0xc0                          ; volume ID
  db 'NO NAME    '              ; volume label
  db 'FAT16   '                 ; file system type
   
  ;db 0x33 
start:
  push dx
  push es
  mov ah, 8
  int 13h                       ; get drive parameters
  mov [DRIVE_TYPE], bl
  and cx, 3Fh                   ; maximum sector number
  mov [SECTORS_PER_TRACK], cx
  mov [NUMBER_OF_DRIVES], dl
  movzx dx, dh                  ; maximum head number
  add dx, 1
  mov [NUMBER_OF_HEADS], dx
  pop es
  pop dx
  mov [DRIVE_NUMBER], dl

mov ax,0x0003
int 10h
mov ax,0x0e42
int 10h
call gethex
mov [DRIVE_NUMBER],al

xor ah,ah
int 0x13

mov ax,ds
mov es,ax

mov bx,0x1000
mov dl,[DRIVE_NUMBER]
mov dh,0x00
mov ax,0x0212
mov cx,0x0002
int 13h
jc read_loop
mov ax,ds
mov es,ax
mov bx,0x1000
jmp bx

read_loop:

xor ah,ah
int 0x13

mov ax,ds
mov es,ax

mov ax,0x0212
mov bx,0x1000
mov cx,0x0002
mov dh,0x00
mov dl,[DRIVE_NUMBER]

int 0x13
jnc boot_success
mov al,[tries]
dec al
mov [tries],al
cmp al,0
jg read_loop
mov al,4
mov [tries],al
inc byte [DRIVE_NUMBER]
jmp read_loop

boot_success:
mov word ax,[SECTORS_PER_TRACK]
mov word bx,[NUMBER_OF_DRIVES]
mov word cx,[NUMBER_OF_HEADS]
mov byte dh,[DRIVE_TYPE]
jmp 0x1000
jmp read_loop

gethex:
call getkey
call printf
call atohex
shl al,4
mov [tries],al

call getkey
call printf
call atohex
mov ah,[tries]
add al,ah
ret

printf:
pusha
mov ah,0x0e
int 10h
popa
ret

getkey:
mov ah,0x00
int 16h
ret

atohex:
cmp al,0x3a
jle hex_num_found
cmp al,0x5a
jg hex_small_found
add al,0x20
hex_small_found:
sbb al,0x28
hex_num_found:
sbb al,0x2f
ret

DRIVE_TYPE:
db 0x00
DRIVE_NUMBER:
db 0x00
SECTORS_PER_TRACK:
dw 0x0000
NUMBER_OF_DRIVES:
dw 0x0000
NUMBER_OF_HEADS:
dw 0x0000
tries:
db 0x04
times 507-($-$$) db 0
db 0xac
db 0xcb
db 0xd8
db 0x55
db 0xaa